﻿using System;
using System.Linq;
using Microsoft.Xna.Framework;
using X3DXNA.interfaces;
using X3DXNA.X3DSchema;
using X3DXNA.utils;

namespace X3DXNA.core.Interpolators
{
    class MyOrientationInterpolator : IRoutable
    {

        #region Private Fields

        float _fraction;
        Quaternion? _value_changed;

        #endregion

        #region Public Properties

        public String DEF { get; set; }
        public float[] key { get; set; }
        public Quaternion[] keyValue { get; set; }
        public float fraction { private get { return _fraction; } set { _fraction = value; recalculateValueChanged(); } }
        public Quaternion? value_changed 
        { 
            get 
            {
                if (_value_changed != null)
                    return (Quaternion)_value_changed;
                else
                    return null;
            } 
            private set { _value_changed = (Quaternion)value; } 
        }

        #endregion

        #region Constructor

        public MyOrientationInterpolator(String DEF, float[] key, Quaternion[] keyValue)
        {
            this.DEF = DEF;
            this.key = key;
            this.keyValue = keyValue;

            _fraction = 0;
            _value_changed = null;
            recalculateValueChanged();
        }

        #endregion

        #region Private Methods

        private void recalculateValueChanged()
        {
            if (_fraction < key.First())
                _value_changed = keyValue.First();
            else if (_fraction > key.Last())
                _value_changed = keyValue.Last();
            else
            {
                for (int i = 0; i < key.Length - 1; i++)
                {
                    if (_fraction > key[i] && _fraction < key[i + 1])
                    {
                        float valueBetweenTwoKeys = (_fraction - key[i]) / (key[i + 1] - key[i]);
                        _value_changed = Quaternion.Lerp(keyValue[i], keyValue[i + 1], valueBetweenTwoKeys);
                        break;
                    }
                }
            }
        }

        #endregion

        #region Public Static Builder

        public static MyOrientationInterpolator getNewPositionInterpolator(OrientationInterpolator ci)
        {
            return new MyOrientationInterpolator(ci.DEF, utility.stringToFloatArray(ci.key), utility.stringToQuaternionArray(ci.keyValue));
        }

        #endregion

    }
}
